#ifndef _ELF_H
#define _ELF_H

#include "types.h"
#define ELF_MAGIC 0x464C457FU
typedef struct {
  int phent;
  int phnum;
  int is_supervisor;
  size_t phdr;
  size_t phdr_size;
  size_t bias;
  size_t entry;
  size_t brk_min;
  size_t brk;
  size_t brk_max;
  size_t mmap_max;
  size_t stack_top;
  size_t time0;
  size_t cycle0;
  size_t instret0;
  char file_name[50];
  bool holdsInfo;
} elf_info;

extern elf_info current_elf_msg;
struct  proc;
void init_elf_msg_by_argv0(elf_info * current_elf_msg,struct proc *p);

typedef struct {
  uint8  e_ident[16];
  uint16 e_type;
  uint16 e_machine;
  uint32 e_version;
  uint64 e_entry;
  uint64 e_phoff;
  uint64 e_shoff;
  uint32 e_flags;
  uint16 e_ehsize;
  uint16 e_phentsize;
  uint16 e_phnum;
  uint16 e_shentsize;
  uint16 e_shnum;
  uint16 e_shstrndx;
} Elf_Ehdr;



typedef struct {
  uint32 p_type;
  uint32 p_flags;
  uint64 p_offset;
  uint64 p_vaddr;
  uint64 p_paddr;
  uint64 p_filesz;
  uint64 p_memsz;
  uint64 p_align;
} Elf_Phdr;


#define PT_LOAD 1

#define IS_ELF(hdr) \
  ((hdr).e_ident[0] == 0x7f && (hdr).e_ident[1] == 'E' && \
   (hdr).e_ident[2] == 'L'  && (hdr).e_ident[3] == 'F')

#define IS_ELF64(hdr) (IS_ELF(hdr) && (hdr).e_ident[4] == 2)


int exec(char *path, char **argv);
int do_exec(char *path, char **argv);
#endif
